
package com.platform.modules.mall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.Constant;
import com.platform.common.utils.JedisUtil;
import com.platform.common.utils.Query;
import com.platform.common.utils.StringUtils;
import com.platform.modules.mall.dao.MallGoodsDao;
import com.platform.modules.mall.dao.MallGoodsToActivityDao;
import com.platform.modules.mall.entity.*;
import com.platform.modules.mall.service.*;
import org.apache.poi.util.ArrayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品表Service实现类
 *
 * @author
 * @date 2019-07-03 17:58:29
 */
@Service("mallGoodsService")
public class MallGoodsServiceImpl extends ServiceImpl<MallGoodsDao, MallGoodsEntity> implements MallGoodsService {
    @Autowired
    private MallAttachmentService attachmentService;
    @Autowired
    private MallGoodsAttributeService goodsAttributeService;
    @Autowired
    private MallSpecificationService specificationService;
    @Autowired
    private MallGoodsSkuService goodsSkuService;
    @Autowired
    private MallOrderGoodsService orderGoodsService;
    @Autowired
    private MallShopsGoodsService shopsGoodsService;
    @Autowired
    private MallSeckillService seckillService;
    @Autowired
    private MallActivityService activityService;
    @Autowired
    JedisUtil jedisUtil;
    @Autowired
    private MallGoodsToActivityService goodsToActivityService;

    @Lazy
    @Resource
    private MallCardSnService snService;

    @Override
    public int undelete(List<String> ids) {
        return baseMapper.undelete("\""+String.join("\",\"",ids)+"\"");
    }

    @Override
    public List<MallGoodsEntity> queryAll(Map<String, Object> params) {
        return baseMapper.queryAll(params);
    }

    @Override
    public Page queryPage(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.ID");
        params.put("asc", false);
        Page<MallGoodsEntity> page = new Query<MallGoodsEntity>(params).getPage();
        return page.setRecords(baseMapper.selectMallGoodsPage(page, params));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(MallGoodsEntity mallGoods) {
        if (StringUtils.isNotBlank(mallGoods.getShopsGoodsId())) {
            // 商户添加的商品增加标识
            mallGoods.setType("1");
        }
        this.save(mallGoods);
        shopsGoodsService.add(mallGoods);
        //轮播图
        List<MallAttachmentEntity> attachmentEntities = mallGoods.getAttachmentEntityList();
        if (null != attachmentEntities && attachmentEntities.size() > 0) {
            for (MallAttachmentEntity attachmentEntity : attachmentEntities) {
                attachmentEntity.setBussinessId(mallGoods.getId());
            }
        }
        attachmentService.saveBatch(attachmentEntities);

        //商品详情页参数列表
        List<MallGoodsAttributeEntity> goodsAttributeEntityList = mallGoods.getGoodsAttributeEntityList();
        if (null != goodsAttributeEntityList && goodsAttributeEntityList.size() > 0) {
            for (MallGoodsAttributeEntity goodsAttributeEntity : goodsAttributeEntityList) {
                goodsAttributeEntity.setGoodsId(mallGoods.getId());
            }
        }
        goodsAttributeService.saveBatch(goodsAttributeEntityList);

        //商品SKU键表
        List<MallSpecificationEntity> specificationEntityList = mallGoods.getSpecificationEntityList();
        if (null != specificationEntityList && specificationEntityList.size() > 0) {
            for (MallSpecificationEntity specificationEntity : specificationEntityList) {
                specificationEntity.setGoodsId(mallGoods.getId());
            }
        }
        specificationService.saveBatch(specificationEntityList);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(MallGoodsEntity mallGoods) {
        Map<String, Object> params = new HashMap<>(2);

        // 店铺关联
        params.put("GOODS_ID", mallGoods.getId());
        List<MallShopsGoodsEntity> list = shopsGoodsService.list(new LambdaQueryWrapper<MallShopsGoodsEntity>()
                .select(MallShopsGoodsEntity::getShopsId, MallShopsGoodsEntity::getId)
                .eq(MallShopsGoodsEntity::getGoodsId, mallGoods.getId()));
        if (list != null && list.size() == 1) {
            if (shopsGoodsService.removeByMap(params)) {
                mallGoods.setShopsId(list.get(0).getShopsId());
                shopsGoodsService.add(mallGoods);
            }
        }

        //轮播图
        params = new HashMap<>(2);
        params.put("BUSSINESS_ID", mallGoods.getId());
        attachmentService.removeByMap(params);
        List<MallAttachmentEntity> attachmentEntities = mallGoods.getAttachmentEntityList();
        if (null != attachmentEntities && attachmentEntities.size() > 0) {
            for (MallAttachmentEntity attachmentEntity : attachmentEntities) {
                attachmentEntity.setBussinessId(mallGoods.getId());
            }
        }
        attachmentService.saveBatch(attachmentEntities);

        //商品详情页参数列表
        params = new HashMap<>(2);
        params.put("GOODS_ID", mallGoods.getId());
        goodsAttributeService.removeByMap(params);
        List<MallGoodsAttributeEntity> goodsAttributeEntityList = mallGoods.getGoodsAttributeEntityList();
        if (null != goodsAttributeEntityList && goodsAttributeEntityList.size() > 0) {
            for (MallGoodsAttributeEntity goodsAttributeEntity : goodsAttributeEntityList) {
                goodsAttributeEntity.setGoodsId(mallGoods.getId());
            }
        }
        goodsAttributeService.saveBatch(goodsAttributeEntityList);

        //商品SKU键表
        specificationService.removeByMap(params);
        List<MallSpecificationEntity> specificationEntityList = mallGoods.getSpecificationEntityList();
        if (null != specificationEntityList && specificationEntityList.size() > 0) {
            for (MallSpecificationEntity specificationEntity : specificationEntityList) {
                specificationEntity.setGoodsId(mallGoods.getId());
            }
        }
        specificationService.saveBatch(specificationEntityList);
        return this.updateById(mallGoods);
    }

    @Override
    public boolean delete(String id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(String[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

    @Override
    public MallGoodsEntity queryById(String id) {
        MallGoodsEntity goodsEntity = this.getById(id);

        Map<String, Object> params = new HashMap<>(4);
        if (goodsEntity == null) {
            return null;
        }

        //轮播图
        params.put("bussinessId", goodsEntity.getId());
        List<MallAttachmentEntity> attachmentEntities = attachmentService.queryAll(params);
        goodsEntity.setAttachmentEntityList(attachmentEntities);

        //商品详情页参数列表
        params = new HashMap<>(4);
        params.put("goodsId", goodsEntity.getId());
        List<MallGoodsAttributeEntity> goodsAttributeEntityList = goodsAttributeService.queryAll(params);
        goodsEntity.setGoodsAttributeEntityList(goodsAttributeEntityList);

        //商品SKU键表
        List<MallSpecificationEntity> specificationEntityList = specificationService.queryAll(params);
        goodsEntity.setSpecificationEntityList(specificationEntityList);

        //商品SKU值表
        List<MallGoodsSkuEntity> goodsSkuEntityList = goodsSkuService.queryAll(params);
        goodsEntity.setGoodsSkuEntityList(goodsSkuEntityList);
        return goodsEntity;
    }

    @Override
    public int changeSale(String[] ids) {
        MallGoodsEntity commentEntity = this.getById(ids[0]);
        if (commentEntity.getIsOnSale() == 1) {
            commentEntity.setIsOnSale(0);
        } else {
            commentEntity.setIsOnSale(1);
        }
        return baseMapper.updateById(commentEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean backGoodsNumber(MallOrderEntity order) {
        String orderId = order.getId();
        String shopsId = order.getShopsId();
        Integer orderType = order.getOrderType();
        //订单下的商品列表
        List<MallOrderGoodsEntity> orderGoodsEntities = orderGoodsService.lambdaQuery().eq(MallOrderGoodsEntity::getOrderId, orderId).list();
        if (null != orderGoodsEntities && orderGoodsEntities.size() > 0) {
            orderGoodsEntities.forEach(orderGoods -> {
                //秒杀订单
                if (orderType == 3) {
                    //取消的订单释放商品库存
                    MallSeckillEntity seckillEntity = seckillService.getOne(new QueryWrapper<MallSeckillEntity>().eq("GOODS_ID", order.getGoodsId()), false);
                    if (null != seckillEntity) {
                        seckillEntity.setStock(seckillEntity.getStock() + orderGoods.getNumber());
                        seckillService.update(seckillEntity);
                    }
                } else {
                    //加库存
                    MallGoodsEntity goodsVo = getById(orderGoods.getGoodsId());
                    goodsVo.setGoodsNumber(goodsVo.getGoodsNumber() + orderGoods.getNumber());
                    goodsVo.setSellVolume(goodsVo.getSellVolume()-orderGoods.getNumber());
                    updateById(goodsVo);
                    //商城订单
                    if (orderType == 1) {
                        if (StringUtils.isNotBlank(orderGoods.getSkuId())) {
                            MallGoodsSkuEntity goodsSkuEntity = goodsSkuService.getById(orderGoods.getSkuId());
                            goodsSkuEntity.setGoodsNumber(goodsSkuEntity.getGoodsNumber() + orderGoods.getNumber());
                            goodsSkuService.update(goodsSkuEntity);
                        }
                    } else if (orderType == 2) {
                        //店铺自提订单
                        MallShopsGoodsEntity shopsGoodsEntity = shopsGoodsService.getOne(new LambdaQueryWrapper<MallShopsGoodsEntity>()
                                        .eq(MallShopsGoodsEntity::getGoodsId, goodsVo.getId())
                                        .eq(MallShopsGoodsEntity::getShopsId, shopsId)
                                , false);
                        shopsGoodsEntity.setGoodsNumber(shopsGoodsEntity.getGoodsNumber() + orderGoods.getNumber());
                        shopsGoodsService.update(shopsGoodsEntity);
                    }

                    boolean isActivity = StringUtils.isNotBlank(order.getActivityId());
                    MallGoodsEntity goodsEntity = this.getById(orderGoods.getGoodsId());
                    Boolean isLLShops = goodsEntity.getThirdSysNumber().equals(MallGoodsEntity.SysNumber.LL.getValue());
                    if(isActivity){
//                        try {
                            String goodsToActivityId = goodsToActivityService.lambdaQuery()
                                    .select(MallGoodsToActivityEntity::getId)
                                    .eq(MallGoodsToActivityEntity::getActivityId,order.getActivityId())
                                    .eq(MallGoodsToActivityEntity::getGoodsId,orderGoods.getGoodsId()).one().getId();
                            // redis加库存
                            jedisUtil.hincrBy(Constant.ACTIVITY_DETAILS_STOCK+order.getActivityId(),goodsToActivityId,orderGoods.getNumber().longValue());
                            // 活动加库存
                            goodsToActivityService.lambdaUpdate()
                                    .setSql("expend_count = expend_count + " + orderGoods.getNumber())
                                    .eq(MallGoodsToActivityEntity::getId,goodsToActivityId)
                                    .update();
//                        }catch (Exception e){
//                            e.printStackTrace();
//                        }
                    }
                }
            });
        }
        return true;
    }

    @Override
    public void setGoodsRedisCount(String activityId) {
        MallActivityEntity activity = activityService.getById(activityId);
        // 查询商品详情
        int timeSize = JSONObject.parseArray(activity.getActivityTime()).size();
        Map<String,Object> params = new HashMap<>(8);
        params.put("start",0);
        params.put("end",timeSize);
        params.put("activityId",activityId);
        List<Map<String,String>> goodsList = ((MallGoodsToActivityDao)goodsToActivityService.getBaseMapper()).getGoodsDetails(params);
        int expire = 86400 - LocalTime.now().toSecondOfDay();

        // 商品时段下标
        final Map<String,String> goodsIndex = new HashMap<>(goodsList.size() + goodsList.size() / 2);

        // 库存 存入redis
        final Map<String,String> stock = new HashMap<>(goodsList.size() + goodsList.size() / 2);
        goodsList.forEach(x->{
            stock.put(x.get("id"),String.valueOf(x.get("expendCount")));
            goodsIndex.put(x.get("goodsId"),x.get("dayOfWeek"));
        });
        jedisUtil.setMap(Constant.ACTIVITY_DETAILS_STOCK+activityId,stock,expire);
        jedisUtil.setMap(Constant.ACTIVITY_GOODS_TIME_INDEX+activityId,goodsIndex,expire);
    }

    @Override
    public void minusGoodsNumber(MallGoodsEntity goods, int number) {
        // 减商品库存
        if (!this.lambdaUpdate().setSql("GOODS_NUMBER = GOODS_NUMBER - " + number)
                .eq(MallGoodsEntity::getId, goods.getId())
                .ge(MallGoodsEntity::getGoodsNumber, number)
                .update()) {
            throw new BusinessException("商品库存不足..");
        }
        // 判断卡券密钥库存
        switch (MallGoodsEntity.GoodsType.values()[goods.getGoodsType()]) {
            case CARD:
                if (snService.count(new QueryWrapper<MallCardSnEntity>().eq("goods_Id", goods.getId()).eq("status", "0")) < number) {
                    throw new BusinessException("商品库存不足...");
                }
                break;
            default:
                break;
        }
    }


    /**
     *
     * @param goodsId   商品id
     * @param num       购买数量
     * @param limitedNum    限制数量
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public MallGoodsEntity shopping(String goodsId, Integer num, Integer limitedNum) {

        MallGoodsEntity goods = this.getById(goodsId);
        if (goods==null){
            throw new BusinessException("抢购的商品不存在",-1);
        }
        /*查看商品是否删除*/
        if (goods.getIsDelete()==0||goods.getIsOnSale()==0){
            throw new BusinessException("该商品已经下架，不能抢购",-1);
        }
        /*是否限购，购买数量是否超过限购数量*/
        if ((limitedNum!=null && num>limitedNum ) || ( goods.getIsLimited() !=0 && num >goods.getIsLimited())){
            throw new BusinessException("购买失败，该商品限购数量为："+limitedNum,-1);
        }
        /*减扣库存，库存数量充足的时候购买成功*/
        int i = baseMapper.goShopping(goodsId, num);
        if (i>0){
            return goods;
        }
        return null;
    }

    @Override
    public MallGoodsEntity shoppingNotException(String goodsId, Integer num, Integer limitedNum) {
        MallGoodsEntity goods = this.getById(goodsId);
        if (goods==null){
            return null;
        }
        /*查看商品是否删除*/
        if (goods.getIsDelete()==0||goods.getIsOnSale()==0){
           return null;
        }
        /*是否限购，购买数量是否超过限购数量*/
        if ((limitedNum!=null && num>limitedNum ) || ( goods.getIsLimited() !=0 && num >goods.getIsLimited())){
           return null;
        }
        /*减扣库存，库存数量充足的时候购买成功*/
        int i = baseMapper.goShopping(goodsId, num);
        if (i>0){
            return goods;
        }
        return null;
    }
}
